package repository

import (
	"ruanGongKeShe16Zu/db"
	"ruanGongKeShe16Zu/model"
	"ruanGongKeShe16Zu/service/vo"

	"gorm.io/gorm"
)

type ICartRepository interface {
	Create(cart *model.Cart) (*model.Cart, error)
	SelectById(id int) (*model.Cart, error)
	Update(cart model.Cart, newCart vo.CartReq) (*model.Cart, error)
	DeleteById(id int) error
	CartList() ([]*model.Cart, error)
	SelectByUserID(req *vo.ListCartReq, id uint) ([]*model.Cart, error)
	DeleteByUserID(id uint) error
}

type CartRepository struct {
	DB *gorm.DB
}

func NewCartRepository() ICartRepository {
	return CartRepository{DB: db.GetDB()}
}

func (repo CartRepository) Create(cart *model.Cart) (*model.Cart, error) {
	if err := repo.DB.Create(&cart).Error; err != nil {
		return nil, err
	}
	return cart, nil
}

func (repo CartRepository) SelectById(id int) (*model.Cart, error) {
	var cart model.Cart
	if err := repo.DB.First(&cart, id).Error; err != nil {
		return nil, err
	}
	return &cart, nil
}

func (repo CartRepository) Update(cart model.Cart, newCart vo.CartReq) (*model.Cart, error) {
	if err := repo.DB.Model(&cart).Updates(newCart).Error; err != nil {
		return nil, err
	}
	return &cart, nil
}

func (repo CartRepository) DeleteById(id int) error {
	cart, err := repo.SelectById(id)
	if err != nil {
		return err
	}
	if err := repo.DB.Delete(cart).Error; err != nil {
		return err
	}
	return nil
}

func (repo CartRepository) CartList() ([]*model.Cart, error) {
	var carts []*model.Cart
	if err := repo.DB.Find(&carts).Error; err != nil {
		return nil, err
	}
	return carts, nil
}

func (repo CartRepository) SelectByUserID(req *vo.ListCartReq, id uint) ([]*model.Cart, error) {
	if req.PageSize != 0 {
		var carts []*model.Cart
		if err := repo.DB.Where("user_id = ?", id).Order("created_at desc").Offset((req.PageNum - 1) * req.PageSize).Limit(req.PageSize).Find(&carts).Error; err != nil {
			return nil, err
		}
		return carts, nil
	}
	var carts []*model.Cart
	if err := repo.DB.Where("user_id = ?", id).Find(&carts).Error; err != nil {
		return nil, err
	}
	return carts, nil
}

func (repo CartRepository) DeleteByUserID(id uint) error {
	carts, err := repo.SelectByUserID(&vo.ListCartReq{}, id)
	if err != nil {
		return err
	}
	if err := repo.DB.Delete(carts).Error; err != nil {
		return err
	}
	return nil
}
